package com.qmerak.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * Basic DAO operations dependent with Hibernate's specific classes
 * 
 * @author shaohong.cheng
 * @date 2013-4-10
 */
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public class HibernateDao<E, K extends Serializable> extends BaseDao {

	protected Class<? extends E> daoType;

	@SuppressWarnings("unchecked")
	public HibernateDao() {
		daoType = (Class<E>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
		// sessionFactory.openSession().clear();
	}

	public E add(E entity) {
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		session.save(entity);
		transaction.commit();
		session.close();
		return entity;
	}

	public void update(E entity) {
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		session.merge(entity);
		// session.saveOrUpdate(entity);
		transaction.commit();
		session.close();
	}

	public void remove(E entity) {
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		session.delete(entity);
		transaction.commit();
		session.close();
	}

	@SuppressWarnings("unchecked")
	public E find(K key) {
		Session session = sessionFactory.openSession();
		E re = (E) session.get(daoType, key);
		session.close();
		return re;
	}

	@SuppressWarnings("unchecked")
	public List<E> list() {
		Session session = sessionFactory.openSession();
		session.clear();
		List<E> re = session.createCriteria(daoType).list();
		session.close();
		return re;
	}
}
